﻿using HAF.Core.Datas;
using HAF.Dispatcher;
using HAF.LogUtility;
using HAF.LogUtility.Assistantor;
using HAF.NetUtility.Assistantor;
using Microsoft.Owin.Hosting;
using RDS.Author;
using RDS.Core;
using RDSEngine.WorkItems;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace RDSEngine
{
    public partial class FrmMainSrv : Form
    {
        public FrmMainSrv()
        {
            InitializeComponent();
        }

        //HttpBaseServer svr;

        private void btnStart_Click(object sender, EventArgs e)
        {
            txtMessages.Clear();
            ShowMessage("准备开始启动金沙引擎");
            Thread httpThread = new Thread(SrvStartThread) { Name = "httpThread", IsBackground = true };
            httpThread.Start();
        }

        private string[] GetAllIps()
        {
            List<string> runips = new List<string>();
            IPAddress[] ips = System.Net.Dns.GetHostAddresses(System.Net.Dns.GetHostName());  //绑定本机所有IP地址
            for (int i = 0; i < ips.Length; i++)
            {
                //if (IPAddress.IsLoopback(ips[i]))
                {
                    if (ips[i].AddressFamily == AddressFamily.InterNetwork) //IPv4地址 
                    {
                        LogHelper.WriteDebugLog(string.Format("当前网络地址{0}为IPv4", ips[i]));
                        runips.Add(ips[i].ToString());
                        //serverListener.Server
                        //Listerner.Prefixes.Add("http://" + ips[i].ToString() + ":" + port.ToString() + "/");
                    }
                    else if (ips[i].AddressFamily == AddressFamily.InterNetworkV6) //IPv6
                    {
                        //runips.Add(ips[i].ToString());
                        LogHelper.WriteDebugLog(string.Format("当前网络地址{0}为IPv6", ips[i]));
                    }
                }
                //else
                //{
                //    LogHelper.WriteDebugLogEx(string.Format("当前网络地址{0}匹配异常", ips[i]));
                //}

            }

            return runips.ToArray();
        }

        IDisposable hostSrv;
        bool _isReg = false;

        private void SrvStartThread()
        {
            try
            {
                InitSrv();
                
                //获取端口号配置
                string port = string.IsNullOrEmpty(ConfigurationManager.AppSettings["DefaultPort"].ToString()) ? 
                    "9100" : ConfigurationManager.AppSettings["DefaultPort"].ToString();
                //获取回馈接口地址
                RuntimeAdapter.WasNotifyUrl = string.IsNullOrEmpty(ConfigurationManager.AppSettings["IptvEngine"].ToString()) ?
                    "http://localhost:8081/WasEngine/Audit/Notify" : ConfigurationManager.AppSettings["IptvEngine"].ToString();
                //获取日志上报接口地址
                RuntimeAdapter.AllowReportLog = string.IsNullOrEmpty(ConfigurationManager.AppSettings["AllowReportLog"].ToString()) ? false :
                    ConfigurationManager.AppSettings["AllowReportLog"].ToString().ToLower() == "true" ? true : false;
                RuntimeAdapter.LogEngine = string.IsNullOrEmpty(ConfigurationManager.AppSettings["LogEngine"].ToString()) ?
                    "http://localhost:8081/WasEngine/Audit/Report" : ConfigurationManager.AppSettings["LogEngine"].ToString();

                //获取主机可用IP
                string[] ips = GetAllIps();
                //var ser = new HttpSelfHostServer();
                if (ips.Length > 0)
                {
                    RuntimeAdapter.HostAddress = ips[0];
                    ShowMessage(string.Format("本机IP： {0}", string.Join(",", ips)));

                    toolStripStatusLabel2.Text = string.Concat("EngineHost: ", RuntimeAdapter.HostAddress);
                }

                //string baseAddress = string.Format("http://127.0.0.1:{0}/", port);  //使用+ 可以在所有网卡直接启动服务，支持IPv6的地址
                //hostSrv = WebApp.Start<Startup>(url: baseAddress);

                foreach (var item in ips)
                {
                    //电脑所有ip地址都启用该端口服务
                    //string baseAddress = string.Format("http://{0}:{1}/", item, port);
                    string baseAddress = string.Format("http://+:{0}/", port);  //使用+ 可以在所有网卡直接启动服务，支持IPv6的地址
                    hostSrv = WebApp.Start<Startup>(url: baseAddress);

                    #region Web Api监听
                    //Assembly.Load("Lind.DDD.TestApi");  //手工加载某个api程序集的controller
                    //var config = new HttpSelfHostConfiguration("http://localhost:3333");
                    //config.Routes.MapHttpRoute("default", "api/{controller}/{id}", new { id = RouteParameter.Optional });
                    //var server = new HttpSelfHostServer(config);
                    //server.OpenAsync().Wait();
                    //Console.WriteLine("Server is opened");
                    #endregion
                }
                //获取当前系统所有目录 string[]转换演示
                RuntimeAdapter.Disks = Directory.GetLogicalDrives();
                string tmpDisks = string.Join(",", RuntimeAdapter.Disks);
                List<string> tmpDisklst = new List<string>(RuntimeAdapter.Disks);
                ShowMessage(string.Format("系统磁盘列表：{0}", tmpDisks));
                
                RuntimeAdapter.NetDisks = new Dictionary<string, bool>();

                ShowMessage(string.Format("金沙引擎启动完成，当前主机监听端口为{0}", port));
                SetButtonState(false);
            }
            catch (Exception ex)
            {
                ShowMessage(string.Format("金沙引擎启动失败\r\n{0}", ex.ToString()));
                LogHelper.WriteErrorLog(string.Format("HTTP服务：方法{0}发生异常：{1}", System.Reflection.MethodBase.GetCurrentMethod().Name, ex.ToString()));
            }

            //HttpListener服务
            //svr = new HttpBaseServer(8040);
            //svr.Start();

        }
        /// <summary>
        /// 初始化服务关联数据
        /// </summary>
        private void InitSrv()
        {
            if (_isReg)
            {
                return;
            }
            //获取当前拷贝设备信息
            RuntimeAdapter.RegistType = "2";
            TokenHelper.GetInstance().GetLocalDeviceInfo();
            Application.DoEvents();
            while (true)
            {
                if (TokenHelper.GetInstance().DeviceReady)
                {
                    break;
                }
                Thread.Sleep(500);
            }
            //系统令牌处理
            TokenHelper.GetInstance().GetChinaToken();

            //获取插件配置信息
            string pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config", "WorkPlugins.json");
            if (System.IO.File.Exists(pluginPath))
            {
                string json = string.Empty;
                using (FileStream fsRead = new FileStream(pluginPath, FileMode.Open, FileAccess.Read))
                {
                    byte[] buffer = new byte[1024];
                    while (true)
                    {
                        int r = fsRead.Read(buffer, 0, buffer.Length);
                        json += new UTF8Encoding(false).GetString(buffer, 0, r);// Encoding.UTF8(false).GetString(buffer, 0, r);
                        if (r == 0)
                        {
                            break;
                        }
                    }
                }
                RuntimeAdapter.RunPugins = JsonAssistant.Deserialize<ThirdPlugins>(json);
            }

            RuntimeAdapter.ShowConsol = ShowMessage;
            RuntimeAdapter.Tasks.Clear();
            _isReg = true;
        }

        int _msgLen = 0;

        private void SetButtonState(bool stat)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<bool>(SetButtonState), stat);
            }
            else
            {
                btnStart.Enabled = stat;
                btnStop.Enabled = !stat;
            }

        }

        private void ShowMessage(string msg)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<string>(ShowMessage), msg);
            }
            else
            {
                if (_msgLen >= 300)
                {
                    txtMessages.Clear();
                    //txtMessages.Text = "";
                    _msgLen = 0;
                }

                txtMessages.Text = txtMessages.Text + (DateTime.Now.ToString() + " " + msg + "\r\n");
                txtMessages.SelectionStart = txtMessages.Text.Length;
                txtMessages.ScrollToCaret();

                _msgLen++;

                //LogHelper.WriteDebugLog(msg);
            }
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            //WebApp.
            //svr.Stop();
            
            hostSrv.Dispose();
            SetButtonState(true);
            timMonitor.Enabled = false;
            RuntimeAdapter.RunRepeat = false;
            ShowMessage("金沙引擎已停止");
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            FrmTest frm = new FrmTest();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                ShowMessage(string.Format("开始检测{0}的可访问性", RuntimeAdapter.HostIP));
                Thread thread = new Thread(delegate ()
                {
                    string rtnStr = CmdAssistant.GetInstance().Ping(RuntimeAdapter.HostIP);
                    ShowMessage(rtnStr);

                    if (RuntimeAdapter.HostPort > 0)
                    {
                        bool rtn = CmdAssistant.GetInstance().Telnet(RuntimeAdapter.HostIP, RuntimeAdapter.HostPort);
                        ShowMessage(string.Format("telnet {0} {1} {2}", RuntimeAdapter.HostIP, RuntimeAdapter.HostPort, rtn ? "成功" : "失败"));
                    }
                })
                { Name = "checkThread", IsBackground = true, Priority = ThreadPriority.Normal };
                thread.Start();
            }

            ////创建HttpCient测试webapi 
            //HttpClient client = new HttpClient();
            ////client.BaseAddress = new Uri(@"http://[ef08::83e7:71e8:1364:0dff]:54502/");  //IPv6地址处理方式
            ////通过get请求数据
            ////var response = client.GetAsync("http://192.168.69.11:9100/api/down").Result;
            //var response = client.GetAsync("http://[fe80::6cbe:9f00:c07c:8927%11]:9100/api/down").Result;
            ////打印请求结果
            //Console.WriteLine(response);
            ////Console.WriteLine(response.Content);
            //ShowMessage(response.ToString());
            //ShowMessage(response.Content.ReadAsStringAsync().Result);
            //Console.WriteLine("Http服务初始化成功！");
        }

        private void FrmMainSrv_Resize(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)    //最小化到系统托盘
            {
                notifyIcon1.Visible = true;    //显示托盘图标
                this.Hide();    //隐藏窗口
            }
        }

        private void notifyIcon1_DoubleClick(object sender, EventArgs e)
        {
            notifyIcon1.Visible = false;
            this.Show();
            WindowState = FormWindowState.Maximized;
            this.Focus();
        }

        private void FrmMainSrv_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                if (MessageBox.Show("金沙引擎还在执行中，是否确定强制退出？", "告警", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                {
                    RuntimeAdapter.RunRepeat = false;
                }
                else
                {
                    e.Cancel = true;
                }

                //notifyIcon1.Visible = true;
                //this.Hide();
            }
        }

        private void FrmMainSrv_Load(object sender, EventArgs e)
        {
            //主界面标题展示名称
            RuntimeAdapter.AppName = string.IsNullOrEmpty(ConfigurationManager.AppSettings["AppCaption"].ToString()) ?
                "资源下载服务 RDS " : ConfigurationManager.AppSettings["AppCaption"].ToString();

            this.Text = string.Concat(RuntimeAdapter.AppName, RuntimeAdapter.AppVersion);
            splitContainer1.Panel1Collapsed = true;
            grpCatch.Visible = true;
            btnStop.Enabled = false;
            timMonitor.Interval = 1 * 60 * 1000;
            
            RuntimeAdapter.AppDir = Application.StartupPath; // Application.ExecutablePath; 包含程序名称
            //RuntimeAdapter.Tasks = new List<RunTask>();
            InitListView();

            if (!FileAssistantor.IsLinkExists("RDSEngine", System.Environment.CurrentDirectory))
            {
                FileAssistantor.CreateNewDesktopShortcut("RDSEngine", Path.Combine(System.Environment.CurrentDirectory, "RDSEngine.exe"), true);
            }
        }

        private void btnCatch_Click(object sender, EventArgs e)
        {
            //collapse 折叠
            splitContainer1.Panel1Collapsed = !splitContainer1.Panel1Collapsed;
            //grpCatch.Visible = !grpCatch.Visible;
            //timMonitor.Enabled = splitContainer1.Panel1Collapsed;
            timMonitor.Enabled = !splitContainer1.Panel1Collapsed;
            if (!splitContainer1.Panel1Collapsed)
            {
                Thread taskThread = new Thread(LoadTaskMessage) { Name = "showTaskThread", IsBackground = true };
                taskThread.Start();
            }
        }

        private void LoadTaskMessage()
        {
            List<RunTask> runs = LoadWorker.GetInstance().ListWorker();
            //填充测试数据
            //runs.Add(new RunTask() { ID = "123412342131", Name = "测试1", Tag = "优朋", Type = "Down", State = 2, CreateTime = DateTime.Now.AddHours(-1), EndTime = DateTime.Now, Comment ="345234bdj399" });
            //runs.Add(new RunTask() { ID = "123412342134", Name = "测试2", Tag = "优朋", Type = "Down", State = 0, CreateTime = DateTime.Now.AddHours(-2), EndTime = DateTime.Now, Comment = "345234bdj399" });
            //runs.Add(new RunTask() { ID = "123412342135", Name = "测试3", Tag = "优朋", Type = "Down", State = 1, CreateTime = DateTime.Now.AddHours(-3), EndTime = DateTime.Now, Comment = "345234bdj399" });
            //runs.Add(new RunTask() { ID = "123412342136", Name = "测试4", Tag = "优朋", Type = "Down", State = 3, CreateTime = DateTime.Now.AddHours(-4), EndTime = DateTime.Now, Comment = "345234bdj399" });
            //runs.Add(new RunTask() { ID = "123412342137", Name = "测试5", Tag = "优朋", Type = "Down", State = 4, CreateTime = DateTime.Now.AddHours(-5), EndTime = DateTime.Now, Comment = "345234bdj399" });
            //runs.Add(new RunTask() { ID = "123412342137", Name = "测试6", Tag = "优朋", Type = "Down", State = 5, CreateTime = DateTime.Now.AddHours(-1.5), EndTime = DateTime.Now, Comment = "345234bdj399" });
            RefreshListview(runs);
        }

        private void InitListView()
        {
            this.lvCatch.Clear();
            //设置列头
            ColumnHeader chName = new ColumnHeader();
            chName.Text = "任务编号";
            chName.Width = 240;
            chName.TextAlign = HorizontalAlignment.Left;
            this.lvCatch.Columns.Add(chName);

            ColumnHeader chFlow = new ColumnHeader();
            chFlow.Text = "任务名称";
            chFlow.Width = 240;
            chFlow.TextAlign = HorizontalAlignment.Left;
            this.lvCatch.Columns.Add(chFlow);

            ColumnHeader chState = new ColumnHeader();
            chState.Text = "状态";
            chState.Width = 80;
            chState.TextAlign = HorizontalAlignment.Left;
            this.lvCatch.Columns.Add(chState);

            ColumnHeader chTag = new ColumnHeader();
            chTag.Text = "来源";
            chTag.Width = 140;
            chTag.TextAlign = HorizontalAlignment.Left;
            this.lvCatch.Columns.Add(chTag);

            ColumnHeader chTime = new ColumnHeader();
            chTime.Text = "创建时间";
            chTime.Width = 120;
            chTime.TextAlign = HorizontalAlignment.Left;
            this.lvCatch.Columns.Add(chTime);

            ColumnHeader chEndTime = new ColumnHeader();
            chEndTime.Text = "结束时间";
            chEndTime.Width = 120;
            chEndTime.TextAlign = HorizontalAlignment.Left;
            this.lvCatch.Columns.Add(chEndTime);
        }

        private void RefreshListview(List<RunTask> runs)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<List<RunTask>>(RefreshListview), runs);
            }
            else
            {
                try
                {
                    if (runs != null && runs.Count > 0)
                    {
                        //按时间排序
                        runs.Sort((x, y) => y.CreateTime.CompareTo(x.CreateTime));
                        lvCatch.BeginUpdate();
                        lvCatch.Items.Clear();
                        int i = 0;
                        foreach (var item in runs)
                        {
                            ListViewItem tmpItem = new ListViewItem();
                            tmpItem.ImageIndex = 0;
                            tmpItem.Name = "subitem" + i.ToString();
                            tmpItem.Text = item.ID;
                            //tmpItem.SubItems.Add();
                            tmpItem.Tag = item.Tag;
                            tmpItem.ToolTipText = item.Comment;
                            tmpItem.SubItems.Add(item.Comment);
                            tmpItem.SubItems.Add(item.StateName);
                            tmpItem.SubItems.Add(item.Name);
                            tmpItem.SubItems.Add(item.CreateTime.ToString());
                            tmpItem.SubItems.Add(item.EndTime.ToString());
                            lvCatch.Items.Add(tmpItem);
                            //lstPlayList.Items.Add(item.LocalUrl, item.ProgramName, 0);
                            i++;
                        }
                        lvCatch.EndUpdate();
                        grpCatch.Text = string.Format("实时监测 [总数：{0} 完成：{1} 执行：{2}]", runs.Count, runs.FindAll(t => t.State == 5).Count, runs.FindAll(t => t.State == 2).Count);
                    }
                    else
                    {
                        grpCatch.Text = "实时监测";
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.WriteErrorLog(ex.ToString());
                }
            }
        }

        private void lvCatch_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            /***********************************
             * 
             * 实现双击打开本地日志文件 
             * 
             ***********************************/
            //lstPlayList.SelectedItems[0].SubItems
            ListViewItem item = this.lvCatch.GetItemAt(e.X, e.Y);
            if (item != null && item.Tag != null)
            {
                //string dateDir = string.Format("{0}{1}/{2}", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
                //string logName = Path.Combine(RuntimeAdapter.AppDir, "Logs", DateTime.Now.ToString("yyyyMM"), DateTime.Now.ToString("dd"), "SysMonitor.log");
                string logName = Path.Combine(RuntimeAdapter.AppDir, "Logs", DateTime.Now.ToString("yyyyMM"), DateTime.Now.ToString("dd"), string.Concat(item.Tag.ToString(), ".log"));
                if (File.Exists(logName))
                {
                    System.Diagnostics.Process.Start("explorer.exe", logName);
                }
                else
                {
                    LogHelper.WriteErrorLog(string.Format("未找到日志文件{0}", logName));
                    if (!string.IsNullOrEmpty(item.Text))
                    {
                        //通过任务编号找到任务请求数据并展示
                        RunTask runItem = RuntimeAdapter.Tasks.Find(t => t.ID == item.Text);
                        if (runItem != null)
                        {
                            ShowDialog(JsonAssistant.Serialize(runItem));
                        }
                        else
                        {
                            ShowDialog(string.Format("未找到日志文件{0}", logName));
                        }
                    }
                    
                }
                
            }
        }

        private void timMonitor_Tick(object sender, EventArgs e)
        {
            LoadTaskMessage();

            //跨日处理
            if (TimeFactory.Instance.IsNextDay(RuntimeAdapter.AppDir))
            {
                //每天清理一次
                LogHelper.WriteDebugLogExt("Clean", "监视工作项：日志清理工作启动！");
                //清理三个月前的日志
                LogHelper.CleanLogs(3 * 30);
            }
        }

        /// <summary>
        /// 弹出消息框
        /// </summary>
        /// <param name="msgStr"></param>
        private void ShowDialog(string msgStr)
        {
            if (!string.IsNullOrEmpty(msgStr))
            {
                MessageBox.Show(msgStr, "告警", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
        }
    }
}
